﻿using Universum.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;
using System.Security.Principal;
using Universum.Model.Services.Classes;
using System;
using System.Web.Mvc;
using Universum.Unit.Tests.Controllers;
using Moq;
using System.Collections;
using Universum.Model.Domain.Classes;
using System.Collections.Generic;
using System.Linq;
using Universum.Views.Classes;

namespace Universum.Unit.Tests
{


	/// <summary>
	///This is a test class for ClassesControllerTest and is intended
	///to contain all ClassesControllerTest Unit Tests
	///</summary>
	[TestClass()]
	public class ClassesControllerTest : with_user_logged
	{


		private TestContext testContextInstance;

		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext
		{
			get
			{
				return testContextInstance;
			}
			set
			{
				testContextInstance = value;
			}
		}

		#region Additional test attributes
		// 
		//You can use the following additional attributes as you write your tests:
		//
		//Use ClassInitialize to run code before running the first test in the class
		//[ClassInitialize()]
		//public static void MyClassInitialize(TestContext testContext)
		//{
		//}
		//
		//Use ClassCleanup to run code after all tests in a class have run
		//[ClassCleanup()]
		//public static void MyClassCleanup()
		//{
		//}
		//
		//Use TestInitialize to run code before running each test
		//[TestInitialize()]
		//public void MyTestInitialize()
		//{
		//}
		//
		//Use TestCleanup to run code after each test has run
		//[TestCleanup()]
		//public void MyTestCleanup()
		//{
		//}
		//
		#endregion


		IList<PageGroup> pageGroups;
		Guid classId = Guid.NewGuid();
		void InitializePageGroups()
		{
			pageGroups = new List<PageGroup>();
			PageGroup uncategorized = new PageGroup
			{
				ID = Guid.NewGuid(),
				ParentGroupId = Guid.Empty,
				Name = "Uncategorized",
				ClassId = classId
			};
			pageGroups.Add(uncategorized);
			PageGroup cuprins = new PageGroup
			{
				ID = Guid.NewGuid(),
				ParentGroupId = Guid.Empty,
				Name = "Incipit",
				ClassId = classId
			};
			pageGroups.Add(cuprins);
			PageGroup child1 = new PageGroup
			{
				ID = Guid.NewGuid(),
				ParentGroupId = cuprins.ID,
				Name = "Sub1",
				ClassId = classId
			};
			pageGroups.Add(child1);
			PageGroup child2 = new PageGroup
			{
				ID = Guid.NewGuid(),
				ParentGroupId = uncategorized.ID,
				Name = "Sub 1 uncategorized",
				ClassId = classId
			};
			pageGroups.Add(child2);
		}
		IList<PageArticle> pageArticles;
		void InitializePageArticles()
		{
			pageArticles = new List<PageArticle>();
			int index = -1;
			for (int i = 0; i < 16; i++)
			{
				if (i % 4 == 0)
				{

					index++;
				}
				PageArticle pa = new PageArticle();
				pa.Publish = pa.Created = DateTime.Now;
				pa.ID = Guid.NewGuid();
				pa.PageGroupId = pageGroups[index].ID;
				pa.Text = "sss";
				pa.Title = "ssss";
				pa.Username = Principal.Identity.Name;

				pageArticles.Add(pa);
			}
		}
		protected override void EstablishContext()
		{
			base.EstablishContext();
			InitializePageGroups();
			InitializePageArticles();
		}
		/// <summary>
		///A test for EditOrCreateContent
		///</summary>
		// TODO: Ensure that the UrlToTest attribute specifies a URL to an ASP.NET page (for example,
		// http://.../Default.aspx). This is necessary for the unit test to be executed on the web server,
		// whether you are testing a page, web service, or a WCF service.
		[TestMethod()]
		//[HostType("ASP.NET")]
		//[UrlToTest("http://localhost/Universum")]
		public void EditOrCreateContentTest()
		{
			EstablishContext();
			// Arrange
			IPrincipal principal = Principal;


			IClassesService classesService = GetMockedClassesService();
			IPageGroupService pageGroupService = GetMockedPageGroupService();
			IPageArticleService pageArticleService = GetMockedPageArticleService();

			ClassesController target = new ClassesController(principal, null, pageArticleService, pageGroupService, classesService, null,null);
			Guid id = classId;
			
			ActionResult actual;
			// Act
			actual = target.EditOrCreateContent(id);
			// Assert
			actual.should_be_of_type<ViewResult>();
			var result = actual.Cast<ViewResult>();
			result.ViewData.Model.should_be_of_type<ClassesEditOrCreateContentViewModel>();
			var model = result.ViewData.Model.Cast<ClassesEditOrCreateContentViewModel>();
			model.Root.Nodes.Count.should_be_equal_to(2);
			model.Root.Nodes[0].ArticleList.Count.should_be_equal_to(4);
			model.Root.Nodes[0].Nodes.Count.should_be_equal_to(1);
			model.Root.Nodes[0].Nodes[0].PageGroup.Name.should_be_equal_to("Sub 1 uncategorized");


		}


		Mock<IClassesService> _MockClassesService;
		Mock<IPageArticleService> _MockPageArtcleService;
		Mock<IPageGroupService> _MockPageGroupService;
		private IClassesService GetMockedClassesService()
		{
			_MockClassesService = new Mock<IClassesService>();



			return _MockClassesService.Object;

		}

		private IPageArticleService GetMockedPageArticleService()
		{
			_MockPageArtcleService = new Mock<IPageArticleService>();
			
			for (int index = 0; index < pageGroups.Count; index++)
			{
				var articles = pageArticles.Where(it => it.PageGroupId == pageGroups[index].ID).ToList();
				var currentId = pageGroups[index].ID;
				_MockPageArtcleService.Setup(
								it => it.GetArticlesByPageGroupId(It.Is<Guid>(it_is => it_is == currentId)))
								.Returns(articles);
			}

			return _MockPageArtcleService.Object;
		}
		private IPageGroupService GetMockedPageGroupService()
		{
			_MockPageGroupService = new Mock<IPageGroupService>();
			_MockPageGroupService.Setup(
				it => it.GetUncategorizedPageGroupByClassId(It.Is<Guid>(id => id == classId)))
				.Returns(pageGroups[0]);
			_MockPageGroupService.Setup(
				it => it.GetPageGroupsByClassId(It.Is<Guid>(id => id == classId)))
				.Returns(pageGroups);
			return _MockPageGroupService.Object;
		}

		
	}
}
